package com.zjw.zy.utils;

import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Point;
import android.media.ExifInterface;
import android.net.Uri;
import android.provider.MediaStore;
import android.view.WindowManager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.zjw.zy.base.ImageEditText;
import com.zjw.zy.bean.ImageInfo;
import com.zjw.zy.bean.RecorderItem;
import com.zjw.zy.MainActivity;

import org.jetbrains.annotations.NotNull;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import ocr.ocr.ui.util.ImageUtil;

/**
 * @author ：zhong.jw
 * @date ：Created in 2022/10/17 16:02
 */
public final class PathUtils {

    private static final String TAG = "PathUtils";

    private static String APP_STORAGE_PATH = "";

    public static final Pattern IMAGE_PATTERN = Pattern.compile("\\$image\\{.+\\}\\$");

    public static void init(@NonNull MainActivity mainActivity) {
        APP_STORAGE_PATH = mainActivity.getFilesDir().getPath();
    }

    public static String getAppStoragePath() {
        return APP_STORAGE_PATH;
    }


    public static String getRecorderPath() {
        String recorderPath = APP_STORAGE_PATH + "/recorder";
        File file = new File(recorderPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        return recorderPath;
    }

    public static String getPrivateImagePath(@NonNull String subPath) {
        String imagePath = APP_STORAGE_PATH + "/image/" + subPath;

        File file = new File(imagePath);
        if (!file.exists()) {
            file.mkdirs();
        }
        return imagePath;
    }


    @Nullable
    public static String saveBitmapToPrivatePath(@NonNull Bitmap bitmap, @NonNull String subPath) {
        String path = getPrivateImagePath(subPath);

        String filePath = path + "/" + bitmap.hashCode() + ".png";
        try (FileOutputStream outputStream = new FileOutputStream(filePath)) {
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
            return filePath;
        } catch (Exception e) {
            LogUtils.e(TAG, "saveBitmapToPrivatePath " + e.getMessage());
        }
        return null;
    }

    public static String genericRecorderFilePath() {
        String recorderPath = APP_STORAGE_PATH + "/recorder";
        File file = new File(recorderPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        File[] files = file.listFiles();
        int count = files == null ? 0 : files.length;
        TimeUtils.TimeBean timeBean = TimeUtils.currentTime();
        String targetPath = recorderPath + "/recorder_" + count + "_" +
                timeBean.getYear() + "_" + timeBean.getMonth() + "_"
                + timeBean.getDay() + "_" + timeBean.getHour() + "_" + timeBean.getMinute() + ".mp3";
        try {
            new File(targetPath).createNewFile();
        } catch (IOException ignore) {

        }
        return targetPath;
    }

    public static String genericStartUpImagePath() {
        String recorderPath = APP_STORAGE_PATH + "/startup";
        File file = new File(recorderPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        String targetPath = recorderPath + "/image.jpg";
        try {
            new File(targetPath).createNewFile();
        } catch (IOException ignore) {

        }
        return targetPath;
    }

    public static List<RecorderItem> requireSDCardRecorder(Context context) {
        List<RecorderItem> data = new ArrayList<>();

        //游标获取SD卡内的数据
        Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.AudioColumns.IS_MUSIC);

        if (cursor.moveToFirst()) {
            do {
                int duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
                int size = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));


                String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
                String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
                String url = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));

                RecorderItem mp3 = new RecorderItem(0, title, duration, 0, url);

                data.add(mp3);
            } while (cursor.moveToNext());
            cursor.close();
        }
        return data;
    }

    @NotNull
    public static String genericOrcImageFilePath() {
        File file = new File(APP_STORAGE_PATH + "/orc");

        if (!file.exists()) {
            file.mkdirs();
        }

        String target = APP_STORAGE_PATH + "/orc/pic.jpg";
        file = new File(target);

        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                LogUtils.e(TAG, e.getMessage());
            }
        }
        return target;
    }


    public static String getImageRealPathFromURI(Uri contentURI) {
        String result;
        Cursor cursor = null;
        try {
            cursor = AppUtils.getMainActivity().getContentResolver().query(contentURI, null, null, null, null);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        if (cursor == null) {
            result = contentURI.getPath();
        } else {
            cursor.moveToFirst();
            int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            result = cursor.getString(idx);
            cursor.close();
        }
        return result;
    }

    public static void saveImageToPhone(@NonNull Bitmap bitmap) {

        MediaStore.Images.Media.insertImage(AppUtils.getApp().getContentResolver(), bitmap, "无", "无");
    }

    @NonNull
    public static List<String> findImageUrlFromString(@NonNull String src) {
        Matcher matcher = IMAGE_PATTERN.matcher(src);

        List<String> result = new ArrayList<>();

        while (matcher.find()) {
            result.add(matcher.group());
        }

        return result;
    }

    @Nullable
    public static byte[] getBitmapBytesFromPath(@NonNull String path) {
        Bitmap bitmap = getBitmapFromPath(path);
        if (bitmap == null) {
            return null;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);

        bitmap.recycle();
        byte[] bytes = out.toByteArray();
        try {
            out.close();
        } catch (IOException e) {
            LogUtils.e(TAG, e.getMessage());
        }
        return bytes;
    }

    @Nullable
    public static Bitmap getBitmapFromPath(@NonNull String path) {
        //如果是imageUrl格式，先提取出path
        if (path.startsWith(ImageEditText.IMAGE_PRE)) {
            path = path.substring(ImageEditText.IMAGE_PRE.length(), path.length() - ImageEditText.IMAGE_SUFFIX.length());
        }

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        Bitmap original = BitmapFactory.decodeFile(path, options);

        Bitmap bitmap = null;
        try {
            ExifInterface exif = new ExifInterface(path);
            int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            Matrix matrix = new Matrix();
            int rotationInDegrees = ImageUtil.exifToDegrees(rotation);
            if (rotation != 0f) {
                matrix.preRotate(rotationInDegrees);
            }

            // 图片太大会导致内存泄露，所以在显示前对图片进行裁剪。
            int maxPreviewImageSize = 2560;

            int min = Math.min(options.outWidth, options.outHeight);
            min = Math.min(min, maxPreviewImageSize);

            WindowManager windowManager = (WindowManager) AppUtils.getApp().getSystemService(Context.WINDOW_SERVICE);
            Point screenSize = new Point();
            windowManager.getDefaultDisplay().getSize(screenSize);
            min = Math.min(min, screenSize.x * 2 / 3);

            options.inSampleSize = ImageUtil.calculateInSampleSize(options, min, min);
            options.inScaled = true;
            options.inDensity = options.outWidth;
            options.inTargetDensity = min * options.inSampleSize;
            options.inPreferredConfig = Bitmap.Config.RGB_565;

            options.inJustDecodeBounds = false;
            bitmap = BitmapFactory.decodeFile(path, options);
        } catch (IOException e) {
            bitmap = original;
        } catch (NullPointerException e) {
            LogUtils.e(TAG, e.getMessage());
        }
        return bitmap;
    }

    @Nullable
    public static String transferImageToPrivatePath(@NonNull Uri uri, @NonNull String filePath) {
        String path = getImageRealPathFromURI(uri);
        File target = new File(path);
        if (!target.exists()) {
            LogUtils.e(TAG, "saveImageToPrivate: !target.exists()");
            return null;
        }
        String name = target.getName();
        String copyPath = filePath + "/" + name;
        File copy = new File(copyPath);

        if (!copy.exists()) {
            try {
                copy.createNewFile();
            } catch (IOException e) {
                LogUtils.e(TAG, e.getMessage());
                return null;
            }
        }

        //文件复制
        try (FileChannel in = new FileInputStream(target).getChannel();
             FileChannel out = new FileOutputStream(copy).getChannel()) {
            out.transferFrom(in, 0, in.size());
        } catch (Exception e) {
            LogUtils.e(TAG, e.getMessage());
            return null;
        }

        return copyPath;
    }

    @NonNull
    public static List<ImageInfo> getImageInfoListFromPath(@NonNull String path) {
        try {
            File file = new File(path);
            if (!file.exists()) {
                LogUtils.e(TAG, "getImagesFromPath !file.exists()");
                return Collections.emptyList();
            }
            if (file.isFile()) {
                return Collections.singletonList(new ImageInfo(path));
            }
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                if (files == null || files.length == 0) {
                    LogUtils.e(TAG, "files == null || files.length == 0");
                    return Collections.emptyList();
                }
                List<ImageInfo> list = new ArrayList<>();
                for (File f : files) {
                    list.add(new ImageInfo(f.getPath()));
                }

                return list;
            }

        } catch (Exception e) {
            LogUtils.e(TAG, e.getMessage());
        }
        return Collections.emptyList();
    }

    public static void deletePath(@NotNull List<String> paths) {
        for (String path : paths) {
            try {
                new File(path).delete();
            } catch (Exception e) {
                LogUtils.e(TAG, e.getMessage());
            }
        }
    }
}

